package cn.xxy.datasource;

import cn.xxy.beans.DataSourceConfig;
import com.alibaba.druid.pool.DruidDataSource;

import javax.sql.DataSource;
import java.util.Map;

public class DruidDataSourceAdapter extends DataSourceAdapter {
    private DruidDataSource ds;
    @Override
    protected DataSource adapter(DataSourceConfig config) {
        ds = new DruidDataSource();
        // 设置数据库连接信息
        ds.setDriverClassName(config.getDriverClass());
        ds.setUsername(config.getUsername());
        ds.setPassword(config.getPassword());
        ds.setUrl(config.getJdbcUrl());
        // 配置连接池参数
        ds.setName(config.getDbName());

        initAdapter();
        injectProperty(ds, config);
        return ds;
    }

    @Override
    protected DataSource adapter(Map<String, String> config) {
        ds = new DruidDataSource();
        initAdapter();
        injectProperty(ds, config);
        return ds;
    }
    protected void initAdapter() {
        if (ds != null) return;
        ds.setInitialSize(10); // 初始化时池中建立的物理连接个数
        ds.setMaxActive(20);  // 最大的可活跃的连接池数量
        ds.setMinIdle(5);    // 最小空闲连接数
        ds.setMaxWait(3000);//获取连接时最大等待时间，单位毫秒，超过连接就会失效

        //#申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        ds.setTestOnBorrow(false);
        //ds.setTimeBetweenEvictionRunsMillis(60000);
        //归还连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能
        ds.setTestOnReturn(false);
        //建议配置为true,不影响性能，并且保证安全性。申请连接的时候检测，如果空闲时间大于timeBetweenEvictionRunsMillis，执行validationQuery检测连接是否有效。
        ds.setTestWhileIdle(false);
        //用来检测连接是否有效的sql，要求是一个查询语句，常用select 'x'
        //ds.setValidationQuery("SELECT 1");
        ds.setPoolPreparedStatements(true);
    }
    /**
     * finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
     *
     * @throws Throwable
     */
    protected void finalize() throws Throwable {
        if (ds != null) {
            ds.close();
        }
        super.finalize();
    }
}